<?php

// +----------------------------------------------------------------------
// | Author: Stupboy King
// +----------------------------------------------------------------------

namespace app\api\controller\driver;

use app\api\logic\Gps;
use app\api\model\Driver;
use app\base\service\Phone;
use app\base\service\Redis;
use think\Controller;
use think\Db;
use think\Request;
use think\Hook;
use think\Config;
use app\api\model;
use app\api\model\Driver as DriverModel;
use app\api\model\Order as OrderModel;
use app\api\logic;
/**
 * @name【司机主页】
 * @baseurl【driver.index】
 * @file【driver/index.php】
 */
class Index extends Base {

    public $redis;
    public $driver;
    public $requestMethod;

    /**
     * @name【司机上班】
     * @desc【司机上班】
     * @uri【onWork】
     * @method【post】
     * @param【
     * dtoken $ string $ abcd $ 校验码 $ 1#
     * lon $ string $ 12 $ 经度 $ 1#
     * lat $ string $ 118 $ 纬度 $ 1#
     * addr $ string $ 泉州 $ 地址 $ 1#
     * status $ int $ 0 $ 0上班 1下班 $ 1
     * 】
     * @return【
     * code $ int $ number|1-1 $ 校验码#
     * msg $ string $  $ 错误信息
     * 】
     */
    public function onWork() {
        $driverInfo = $this->driverInfo;
        $driver_id  = $driverInfo['driver_id'];
        $status     = input('status', 0);
        $status     = $status == 0 ? 3 : 4;
        $lon        = input('lon', 0);
        $lat        = input('lat', 0);
        if (empty($this->dtoken)) {
            return $this->retError(501);
        }
        if ($status == 1 && ($lon == 0 || $lat == 0)) {
            return $this->retError(502);
        }
        $driver = new DriverModel();
        if(empty($driverInfo['car_id'])){
            return $this->retError(127);
        }
        // 检查一辆车绑定多个人时，其他人员是否在班
        list($code,$msg) = $driver->checkCarWork($driverInfo['driver_id'],$driverInfo['car_id']);
        if($code==0){
            return $this->retError($msg);
        }
        $driver->setLocation($driver_id, $lon, $lat);//更新数据库字段
        $this->updateRedisDriverPos($lon,$lat,time()*1000,['work_state'=>$status]);
        $driver->changeStatus($driver_id, $status);
        return $this->retSucc();
    }

    /**
     * @name【听单模式】
     * @desc【听单模式】
     * @uri【WorkType】
     * @method【post】
     * @param【
     * dtoken $ string $ abcd $ 校验码 $ 1#
     * listen_type $ string $ 3 $ 听单模式1日常 2包车 3日常+包车 $ 1#
     * go_type $ string $ 3 $ 出行类型1及时2预约 3及时+预约 $ 1#
     * stime $ string $ 1990-1-1 00:00:00 $ 预约开始时间 #
     * etime $ int $ 2037-1-1 00:00:00  $ 1预约开始时间
     * 】
     * @return【
     * code $ int $ number|1-1 $ 校验码#
     * msg $ string $  $ 错误信息
     * 】
     */
    public function WorkType(){
        $data['listen_type'] = input('listen_type',3);
        $data['go_type']     = input('go_type',3);
        $data['stime']       = input('stime','1990-1-1 00:00:00');
        $data['etime']       = input('etime','2037-1-1 00:00:00');
        $driverSetting       = new model\DriverSetting();
        if($driverSetting->where('driver_id',$this->driverInfo['driver_id'])->find()){
            $driverSetting->save($data,['driver_id'=>$this->driverInfo['driver_id']]);
        }else{
            $data['driver_id']   = $this->driverInfo['driver_id'];
            $driverSetting->save($data);
        }
        return $this->retSucc();
    }

    /**
     * @name【GPS定位回传】
     * @desc【GPS定位回传】
     * @uri【track】
     * @method【post】
     * @param【
     * dtoken $ string $ abcd $ 校验码 $ 1#
     * json_array $ string $ 
     * [{"id":0,"accuracy":5.0,"altitude":66.23,"bearing":0.0,"city":"泉州市","latitude":24.768539826399316,"locationType":1,"longitude":118.54787424031393,"provider":"gps","speed":0.0,"time":1515415271113}] 
     * $ 定位数据 $ 1
     * 】
     * @return【
     * code $ int $ number|1-1 $ 校验码#
     * msg $ string $  $ 错误信息
     * 】
     */
    public function track($json_array, $sort = '') {
        $driverInfo = $this->driverInfo;
        $driver_id  = $driverInfo['driver_id'];
        if (intval($driver_id) == 0) {
            return $this->retError(501);
        }
        $data_array = json_decode($json_array);
        if (is_array($data_array) && !empty($data_array)) {
            $dataLen = count($data_array);
            $dLen    = $dataLen;
            if ($sort == 'desc') {
                $dLen = 1;
            }
            $longitude   = $data_array[$dLen - 1]->longitude;
            $latitude    = $data_array[$dLen - 1]->latitude;
            $data_array[$dLen - 1]->time = time() * 1000;
            $report_time = $data_array[$dLen - 1]->time;
            $time_str    = date('Y-m-d H:i:s', $report_time / 1000);
            if (!empty($longitude) && !empty($latitude)) {
                $this->updateRedisDriverPos($longitude,$latitude,$report_time,['timestr'=>$time_str]);
                // 地址更新写入队列 系统每10秒写入一次数据库
                // (new DriverModel())->setLocation($driver_id,$longitude,$latitude);// 更新司机位置
            }
        }
        $dataArr['data']      = json_decode($json_array,true);
        $dataArr['driver_id'] = $this->driverInfo['driver_id'];
        $ret                  = $this->udpGet(json_encode($dataArr));
        if($ret[0]==1){
            return $this->retSucc();
        }else{
            return $this->retError($ret[1]);
        }
        return $this->retSucc();
    }

    /**
     * @name【获取附近乘客发单】
     * @desc【获取附近乘客发单】
     * @uri【getNearOrder】
     * @method【post】
     * @param【
     *  dtoken $ string $ abcd $ 校验码 $ 1 #
     *  type   $ int $ 1 $类型1今天2明天3后台 $1 #
     * page $ int $ 1 $ 页数 #
     * pagenum $ int $ 10 $ 记录数
     * 】
     * @return【
     * code $ int $ number|1-1 $ 校验码#
     * msg $ string $  $ 错误信息#
     * count $ int $$ 记录数#
     * data $ json $$ 列表$ [{"order_id":4,"order_state":4,"order_type":"3","use_type":"0","booking_type":"0","order_time":"2018-02-03 22:02:56","car_type_id":0,"departure":"16路;晋江3路;晋江6路;晋江8路;晋江11路;晋江12路;晋江15路;晋江20路;晋江21路;晋江32路","destination":"坪山路与泉秀路交汇处西北角","from_addr":"1","from_lon":"11.00000000","from_lat":"1.00000000","to_addr":null,"to_lon":null,"to_lat":null,"plan_time":"2018-02-04 15:08:12"}]
     * 】
     */
    public function getNearOrder(){
        $type     = input('type',1);
        $page     = input('page',1);
        $pagenum  = input('pagenum',10);
        list($data['count'],$data['data']) = OrderModel::getNearOrder($type,$page,$pagenum,$this->driverInfo['driver_id']);
        return $this->retSucc($data);
    }

    /**
     * @name【司机接单】
     * @desc【司机接单】
     * @uri【receiptOrder】
     * @method【post】
     * @param【
     * dtoken $ string $ abcd $ 校验码 $ 1#
     * orderid $ int $ 1 $订单id$1
     * 】
     * @return【
     * code $ int $ number|1-1 $ 校验码#
     * msg $ string $  $ 错误信息
     * 】
     * @note【statu=5】
     */
    public function receiptOrder() {
        $oid                 = input('orderid');
        $driver_id           = $this->driverInfo['driver_id'];
        list($code,$msg)     = (new logic\Driver())->receiveOrder($driver_id,$oid);
        return $this->retAll($code,$msg);
    }

    /**
     * @name【司机取消接单】
     * @desc【司机取消接单】
     * @uri【cancelOrder】
     * @method【post】
     * @param【
     * dtoken $ string $ abcd $ 校验码 $ 1#
     * orderid $ int $ 1 $订单id$1
     * 】
     * @return【
     * code $ int $ number|1-1 $ 校验码#
     * msg $ string $  $ 错误信息
     * 】
     * @note【statu=4】
     */
    public function cancelOrder(){
        return $this->retError(133);
        //$oid                 = input('orderid');
        //$driver_id           = $this->driverInfo['driver_id'];
        //list($code,$msg)     = (new logic\Driver())->cancelOrder($driver_id,$oid);
        //return $this->retAll($code,$msg);
    }

    /**
     * @name【接乘客】
     * @desc【接乘客】
     * @uri【startOrder】
     * @method【post】
     * @param【
     * dtoken $ string $ abcd $ 校验码 $ 1 #
     * lon $ string $ 118.876765 $ 经度 $ `1#
     * lat $ string $ 23.876765 $ 纬度 $ `1#
     * addr $ string $ 泉州 $ 地址 $ `1
     * 】
     * @return【
     * code $ int $ number|1-1 $ 校验码#
     * msg $ string $  $ 错误信息
     * 】
     * @note【statu=6】
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function startOrder() {
        $oid        = input('orderid');
        $driverInfo = $this->driverInfo;
        $driver_id  = $driverInfo['driver_id'];
        $orderTime  = Db::name('order_gps')->where('order_id',$oid)->value('plan_time');
        // 判断司机是否有未执行完订单
        $where['order_state'] = ['in','6,7,8'];
        $hasWorkingOrder = Db::name('order')->whereNull('delete_time')->where($where)->select();
        if(!empty($hasWorkingOrder)){
            //return $this->retError(130);
        }
        // 订单计划出行20分钟内才可以执行订单
        if(strtotime($orderTime) - time() > 60*20){
            return $this->retError(144);
        }
        $ret        = (new OrderModel())->save(['order_state' => 6], ['order_state' => 5, 'driver_id' => $driver_id, 'order_id' => $oid]);
        if ($ret < 1) {
            return $this->retError(404);
        } else {
            (new DriverModel())->changeStatus($driver_id,1);
            (new model\OrderGps())->addOrderGPS('driver_', $oid, input('lon'), input('lat'), input('addr'));
            Hook::listen('start_order',$oid);
            return $this->retSucc();
        }
    }

    /**
     * @name【到达乘客地点】
     * @desc【到达乘客地点】
     * @uri【arrivalStartPlace】
     * @method【post】
     * @param【
     * dtoken $ string $ abcd $ 校验码 $ 1 #
     * lon $ string $ 118.876765 $ 经度 $ `1#
     * lat $ string $ 23.876765 $ 纬度 $ `1#
     * orderid $ int $ 1 $ 订单id $ 1 #
     * start_mile $ int $ 23568 $ 开始里程数 $ 1 #
     * start_pic $ base_64 $ $ 开始里程拍照 $ 1 #
     * addr $ string $ 泉州 $ 地址 $ `1
     * 】
     * @return【
     * code $ int $ number|1-1 $ 校验码#
     * msg $ string $  $ 错误信息
     * 】
     * @note【statu=7】
     */
    public function arrivalStartPlace() {
        $oid        = input('orderid');
        $startMile  = input('start_mile',0);
        $fileString = input('start_pic','');
        $file = '';
        // TODO校验填入里程
        if(!empty($fileString)){
            list($saveState,$file) = $this->saveBase64($fileString,'/');
            if($saveState==0) $file = '';
        }
        $driverInfo = $this->driverInfo;
        $driver_id  = $driverInfo['driver_id'];
        $ret = (new OrderModel())->save(['order_state' => 7, 'arrive_time' => $this->dateTime], ['order_state' => 6, 'driver_id' => $driver_id, 'order_id' => $oid]);
        if ($ret < 1) {
            return $this->retError(404);
        } else {
            (new model\OrderGps())->addOrderGPS('wait_', $oid, input('lon'), input('lat'), input('addr'),$startMile,$file);
            Hook::listen('arrival_order',$oid);
            return $this->retSucc();
        }
    }

    /**
     * @name【获取等待时间】
     * @desc【获取等待时间】
     * @uri【getWaitTime】
     * @method【post】
     * @param【
     * dtoken $ string $ abcd $ 校验码 $ 1 #
     * orderid $ int $ 1 $ 订单id $ 1
     * 】
     * @return【
     * code $ int $ number|1-1 $ 校验码#
     * msg $ string $  $ 错误信息 #
     * wait $ int $$ 等待时间秒
     * 】
     */
    public function getWaitTime(){
        $oid      = input('orderid');
        $waitTime = Db::name('order_gps')->where('order_id',$oid)->value('wait_time');
        $wait     = strtotime($waitTime)>0 ? time() - strtotime($waitTime) : 0;
        return $this->retSucc(['wait'=>$wait]);
    }

    /**
     * @name【载客出发】
     * @desc【载客出发】
     * @uri【doOrder】
     * @method【post】
     * @param【
     * dtoken $ string $ abcd $ 校验码 $ 1 #
     * lon $ string $ 118.876765 $ 经度 $ 1#
     * lat $ string $ 23.876765 $ 纬度 $ 1#
     * addr $ string $ 泉州 $ 地址 $ 1 #
     * start_mile $ int $ 23568 $ 开始里程数 $ 1 #
     * start_pic $ base_64 $ $ 开始里程拍照 $ 1 #
     * wait_time $ int $  600 $等待时间秒 $ 1
     * 】
     * @return【
     * code $ int $ number|1-1 $ 校验码#
     * msg $ string $  $ 错误信息
     * 】
     * @note【statu=7】
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function doOrder() {
        $oid        = input('orderid');
        $startMile  = input('start_mile',0);
        $fileString = input('start_pic','');
        $file = '';
        // TODO校验填入里程
        if(!empty($fileString)){
            list($saveState,$file) = $this->saveBase64($fileString,'/');
            if($saveState==0) $file = '';
        }
        $driverInfo = $this->driverInfo;
        $driver_id  = $driverInfo['driver_id'];
        $wait_time  = input('wait_time',0);
        $orderFee   = new model\OrderFee();
        $gpsWaitTime= Db::name('order_gps')->where('order_id',$oid)->value('wait_time');
        $wait_time  = strtotime($gpsWaitTime)==0 ? $wait_time : time() - strtotime($gpsWaitTime);
        if($orderFee->where("order_id = $oid")->find()){
            $orderFee->save(['wait_time'=>$wait_time],['order_id'=>$oid]);
        }else{
            $orderFee->save(['wait_time'=>$wait_time,'order_id'=>$oid]);
        }
        $where      = ['order_state' => 7, 'driver_id' => $driver_id, 'order_id' => $oid];
        $ret        = (new OrderModel())->save(['ride_time' => $this->dateTime], $where);
        if ($ret < 1) {
            return $this->retError(404);
        } else {
            (new model\OrderGps())->addOrderGPS('go_', $oid, input('lon'), input('lat'), input('addr'),$startMile,$file);
            Hook::listen('go_order',$oid);
            return $this->retSucc();
        }
    }

    /**
     * @name【结束订单】
     * @desc【结束订单】
     * @uri【endOrder】
     * @method【post】
     * @param【
     * dtoken $ string $ abcd $ 校验码 $ 1 #
     * orderid $ int $ 5 $订单id$ 1#
     * use_time $ int $ 678 $订单用时秒$1#
     * meter $ int $ 1230 $ 里程 $ 1#
     * lon $ string $ 118.876765 $ 经度 $ `1#
     * lat $ string $ 23.876765 $ 纬度 $ 1#
     * end_mile $ int $ 23568 $ 结束里程数 $ 1 #
     * end_pic $ base_64 $ $ 结束里程拍照 $ 1 #
     * addr $ string $ 泉州 $ 地址 $ 1
     * 】
     * @return【
     * code $ int $ number|1-1 $ 校验码#
     * msg $ string $  $ 错误信息#
     * data $ json $ $ 数据 $ {"travel_fee":"5.00","meter":"0.00","use_time":0,"time_fee":"0.00","low_time":0,"low_fee":"0.00","remote_meter":"0.00","remote_fee":"0.00","wait_time":0,"wait_fee":"0.00","driver_money":"10.00","track":[]}
     * 】
     * @note【statu=7】
     * @return \think\response\Json
     * @throws \think\exception\DbException
     */
    public function endOrder() {
        $meter      = input('meter',0);
        $user_time  = input('use_time',0);
        $oid        = input('orderid',0);
        $endMile    = input('end_mile',0);
        $fileString = input('end_pic','');
        $orderGps   = model\OrderGps::get(['order_id'=>$oid]);
        $file = '';
        if( $endMile < $orderGps->start_mile ){
            return $this->retError(146);
        }
        if(!$fileString){
            // return $this->retError('里程图片必须上传');
        }else{
            list($fileStatus,$file) = $this->saveBase64($fileString,'/');
            if($fileStatus==0) $file = '';
        }
        list($mile,$low,$night,$track) = (new Gps())->getTrack($this->driverInfo['driver_id'],$orderGps->go_time,date('Y-m-d H:i:s'));
        $user_time = strtotime($orderGps->go_time) >0 ? time() - strtotime($orderGps->go_time) : $user_time;
        $night     = 0;//临时关闭夜间费用
        if($endMile>0 && !empty($file) && intval($orderGps->start_mile)>0){
            $meter     = ($endMile - $orderGps->start_mile)*1000;//根据司机手输里程
        }else{
            $meter     = $meter>$mile ? $meter : $mile;
        }
        $where     = ['order_state' => 7, 'driver_id' => $this->driverInfo['driver_id'], 'order_id' => $oid];
        if((new OrderModel())->save(['order_state' => 8], $where)<1){
            return $this->retError(404);
        }
        $data      = DriverModel::countFee($this->driverInfo['driver_id'],$oid,$user_time,$meter,$low,$night);
        // 里程费 时长费 低速行驶费 远途费 候客费
        (new model\OrderFee())->updateFee($oid,$data);
        (new model\OrderGps())->addOrderGPS('arrival_', $oid, input('lon'), input('lat'), input('addr'),$endMile,$file);
        // TODO费用分解
        $rdata          = (new model\OrderFee())->getDriverFee($oid);
        return $this->retSucc(['data'=>$rdata]);
    }

    /**
     * @name【费用确认】
     * @desc【费用确认】
     * @uri【sureFee】
     * @method【post】
     * @param【
     * dtoken $ string $ abcd $ 校验码 $ 1 #
     * orderid $ int $ 5 $订单id$ 1 #
     * high_fee $ float $ 0.00  $高速费#
     * toll  $ float $ 0.00  $ 路桥费 #
     * park_fee  $ float $ 0.00  $ 停车费 #
     * other_fee  $ float $ 0.00 $ 其他费用 #
     * other_note  $ int $ 无 $ 其他费用备注
     * 】
     * @return【
     * code $ int $ number|1-1 $ 校验码#
     * msg $ string $  $ 错误信息
     * 】
     */
    public function sureFee() {
        $oid                = input('orderid',0);
        $data['high_fee']   = input('high_fee',0);
        $data['toll']       = input('toll',0);
        $data['park_fee']   = input('park_fee',0);
        $data['other_fee']  = input('other_fee',0);
        $data['other_note'] = input('other_note','');
        $data['update_time']= date('Y-m-d H:i:s');
        if($data['other_fee']>0 && empty($data['other_note'])){
            return $this->retError('其他费用大于0时，备注必填');
        }
        if(((new model\OrderFee())->save($data,['order_id'=>$oid]))>0 && ((new model\Order())->save(['order_state'=>9],['order_state'=>8,'order_id'=>$oid]))>0){
            (new model\OrderFee())->countFee($oid);
            $driver = new DriverModel();
            $driver->changeStatus($this->driverInfo['driver_id'], 3);//改变司机状态
            $driver->addOrderCount($this->driverInfo['driver_id']);//增加订单数量
            Hook::listen('sure_fee',$oid);
            return $this->retSucc();
        }else{
            return $this->retError(404);
        }
    }

    /**
     * @name【获取隐号】
     * @desc【获取隐号】
     * @uri【getHidePhone】
     * @method【post】
     * @param【
     *  dtoken $ string $ token $ 校验 $ 1 #
     *  orderid $ int $ 1 $ 订单id $ 1 #
     *  phone1 $ string $ 15559203611 $ 主叫号码 $ 1 #
     *  phone2 $ string $ 15559203611 $ 被叫号码 $ 1
     * 】
     * @return【
     * code $ int    $ number|1-1 $ 校验码#
     * msg  $ string $  $ 错误信息 #
     * data $ string $ $ 电话号码
     * 】
     */
    public function getHidePhone(){
        $phone1 = input('phone1');
        $phone2 = input('phone2');
        $oid    = input('orderid');
        $phone  = (new Phone())->dial_get($phone1,$phone2,$oid);
        if($phone==0 || $phone=='0'){
            return $this->retError(124);
        }
        return $this->retSucc(['data'=>$phone]);
    }

    /**
     * @name【轮询获取推送】
     * @desc【轮询获取推送】
     * @uri【getPush】
     * @method【post】
     * @param【
     *  dtoken $ string $ token $ 校验 $ 1
     * 】
     * @return【
     * code $ int    $ number|1-1 $ 状态#
     * msg  $ string $  $ 描述信息 #
     * data $ string $ $ 数据信息 $ {"order_no":"151805820274267667","order_id":23749,"order_state":4,"order_type":"3","use_type":null,"booking_type":"1","order_time":"2018-02-08 10:50:02","car_type_id":133,"area_id":4,"driver_id":17,"departure":"高林社区","from_lon":"118.17954900","from_lat":"24.50954700","destination":"乌石浦油画村","to_lon":"118.12885600","to_lat":"24.50588300","plan_time":"2018-02-08 10:50:00","call_time":"2018-02-08 10:50:02","type":"2","car_type":"3","law_type":1,"prop":"4","action":"dispatch","notice":"您有一个指派订单，今天 2018-02-08 10:50:00 从 高林社区 到 乌石浦油画村 ，请您注意查收！"}
     * 】
     */
    public function getPush(){
        $redis     = Redis::getInstance();
        $driver_id = $this->driverInfo['driver_id'];
        $key       = $driver_id.'_push';
        $push      = json_decode($redis->get($key),true);
        $data      = $push['msg'] ? : [];
        // 推送时间超过 21 秒则不执行轮询 app端5秒轮询一次
        $pushTime  = time() - $push['time'];
        if($pushTime>30 || $pushTime<6){
            $data = null;
        }else{
            $redis->del($key);
        }
        return $this->retSucc(['data'=>$data]);
    }

    /**
     * @name【版本检查】
     * @desc【版本检查】
     * @uri【getVersion】
     * @method【post】
     * @param【
     *  dtoken $ string $ token $ 校验 $ 1
     * 】
     * @return【
     * code $ int    $ number|1-1 $ 校验码#
     * msg  $ string $  $ 错误信息 #
     * android_version $ string $ $ 版本号 #
     * android_version_name $ string $$ 版本名#
     * url $ string $ $下载地址 #
     * oss_url $ string $ $OSS下载地址 #
     * update_time $ datetime $$更新日期
     * 】
     */
    public function getVersion(){
        $version = (new logic\Version())->checkVersion('driver_app');
        return $this->retSucc($version);
    }

    public function getRedisDriver(){
        $prefix = input('prefix','ucardriver');
        $prefix = $prefix.'.pos.*';
        $ret    = $this->redis->keys($prefix);
        if(empty($ret)){
            return $this->retError();
        }
        $brr    = [];
        foreach($ret as $v){
            $arr              = $this->redis->get($v);
            $arr              = json_decode($arr,true);
            $ids              = explode('.',$v);
            if(count($ids)<2){
                continue;
            }
            $arr['driver_id'] = $ids[2];
            $brr[]            = $arr;
        }
        $data['data'] = $brr;
        return $this->retSucc($data);
    }

    public function _empty(){
        return $this->retError('接口地址错误');
    }
}
